// 1.插件：挂载$store
// 2.实现Store

let Vue;
class Store {
  constructor(options) {
    // data响应式处理
    // this.$store.state.xxx
    this._vm = new Vue({
      data: {
        $$state: options.state,
      },
      computed: {},
    });

    this._mutations = options.mutations;
    this._actions = options.actions;

    this.commit = this.commit.bind(this);
    this.dispatch = this.dispatch.bind(this);
    // 加入了计算属性
    this._wrappedGetters = options.getters;
    // 定义computed选项
    const computed = {};
    this.getters = {};
    const store = this;
    Object.keys(this._wrappedGetters).forEach((key) => {
      // 获取用户定义的getter
      const fn = store._wrappedGetters[key];
      // 转换为computed可以使用无参数形式
      computed[key] = function() {
        return fn(store.state);
      };
      // 为getters定义只读属性
      Object.defineProperty(store.getters, key, {
        get() {
          return store._vm[key];
        },
      });
    });

    // 没有加入到计算属性
    // this.getters = options.getters;
    // let that = this;
    // Object.keys(this.getters).forEach((key) => {
    //   const func = this.getters[key];
    //   Object.defineProperty(this.getters, key, {
    //     get() {
    //       return func(that.state);
    //     },
    //   });
    // });
  }

  get state() {
    return this._vm._data.$$state;
  }

  set state(v) {
    console.error("please use replaceState to reset state");
  }

  commit(type, payload) {
    const entry = this._mutations[type];
    if (!entry) {
      console.error("unkonw");
    }
    entry(this.state, payload);
  }

  dispatch(type, payload) {
    const entry = this._actions[type];
    if (!entry) {
      console.error("unkonw");
    }
    entry(this, payload);
  }
}

// Vue.use
// install.apply(this,[this,...])
function install(_Vue) {
  Vue = _Vue;

  Vue.mixin({
    beforeCreate() {
      if (this.$options.store) {
        Vue.prototype.$store = this.$options.store;
      }
    },
  });
}

export default { Store, install };
